# @Time : 2024-11-11 17:06
# @Author : Fioman 
# @Phone : 13149920693
"""
eap的客户端和服务的操作类,外部调用的时候,调用这个函数
"""
import threading
import time

import gevent
from flask import Flask, request, jsonify

import app_config
from app.device_state import DeviceState
from common.datetime_helper import get_datatime_now_str
from eap_control import eap_request, resp_parse
from eap_control.eap_config import EapConfig
from eap_control.eap_logger import EapLogger
from personal_tool.data_result import DataResult
from web_tool.send_to_web_handler import update_eap_data_model_in_web, update_eap_orders_in_web
from web_tool.tool_data_model import EapDataType

ec = EapConfig()
eapLog = EapLogger()
ds = DeviceState()
app = Flask(__name__)


@app.route('/EAPWebApi/EQP/<method>', methods=['POST'])
def api_method(method):
    """
    处理Post请求
    :param method:
    :return:
    """
    try:
        # if request.content_type != 'application/json; charset=utf-8':
        if 'application/json' not in request.content_type:
            eapLog.print_and_debug(f"request.content_type Error: 接收类型: {request.content_type}")
            return jsonify({'error': 'Content-Type must be application/json'}), 400
        data = request.json
        eapLog.print_and_debug(f"从Eap接收请求: method={method}, data={data}")
        response = EapHandler.deal_eap_reqeust(method, data)
        if response is None:
            eapLog.print_and_debug(f"in api_method() 未处理的Eap请求消息: {method},响应消息为None")
        return jsonify(response)
    except Exception as e:
        eapLog.print_and_debug(f"in api_method: {str(e)}")
        return jsonify({'error': str(e)}), 400


class EapHandler:
    cimMessageUpdateFlag = False
    def __init__(self):
        self.requestThread = threading.Thread(target=self.request_listener, daemon=True)
        self.recvThread = threading.Thread(target=self.flask_app_listener, daemon=True)
        self.currentTimeThread = threading.Thread(target=self.report_current_time, daemon=True)
        self.wipCountThread = threading.Thread(target=self.wip_count_report, daemon=True)

    
    @staticmethod
    def close_cim_message_handler():
        EapHandler.cimMessageUpdateFlag = False

    @staticmethod
    def user_login_logout_from_web(work_type: str, user_no: str):
        """
        web界面点击上下岗按钮之后调用的逻辑
        :param work_type: "登入" 表示登入, "登出" 表示登出
        :param user_no: 操作员工号
        :return: DataResult
        """
        from eap_control import eap_request, resp_parse
        methodName = "UserLoginLogoutReport"
        return eap_request.request_user_login_logout_report(methodName, work_type=work_type, user_no=user_no)

    @staticmethod
    def wip_count_report():
        while app_config.isMainAlive:
            if ec.eapOnline:
                methodName = "EquipmentTotalCount"
                response = eap_request.request_equipment_total_count(ds.totalWipCount)
                resp_parse.parse_equipment_total_count_response(methodName, response)
                gevent.sleep(ec.wip_count_duration)
            else:
                gevent.sleep(3)  # 如果Eap不在线,就3秒监控一次Eap的状态

    @staticmethod
    def report_current_time():
        while app_config.isMainAlive:
            if ec.eapOnline:
                gevent.sleep(ec.time_report_duration)
                response = eap_request.request_equipment_current_date_time()
                resp_parse.parse_equipment_current_date_time_response(response)
            else:
                gevent.sleep(3)  # 如果Eap不在线,就3秒监控一次

    @staticmethod
    def request_listener():
        while app_config.isMainAlive:
            response = eap_request.request_are_you_there()
            result = resp_parse.parse_are_you_there_response("AreYouThereRequest", response)
            if result.state:
                ec.eapOnline = True
            else:
                ec.eapOnline = False
            update_eap_data_model_in_web(EapDataType.eapOnline, ec.eapOnline)
            time.sleep(ec.ask_duration)

    @staticmethod
    def flask_app_listener():
        app.run(host="0.0.0.0", port=ec.pcPort)

    def thread_start(self):
        if not self.requestThread.is_alive():
            self.requestThread.start()
        if not self.recvThread.is_alive():
            self.recvThread.start()
        if not self.currentTimeThread.is_alive():
            self.currentTimeThread.start()
        if not self.wipCountThread.is_alive():
            self.wipCountThread.start()

    @staticmethod
    def deal_eap_reqeust(methodName, data):
        """
        处理Eap的请求,根据请求的方法和消息内容
        :return:
        """
        if methodName == "InitialDataRequest":
            response = EapHandler.get_initial_data_request_replay()
        elif methodName == "TraceDataRequest":
            response = EapHandler.get_trace_data_request_replay()
        elif methodName == "CIMMessageCommand":
            response = eap_request.deal_cim_message_command(data)
        elif methodName == "FilePathAndLotInformationDownload":
            response = eap_request.request_file_path_and_lot_information_download(data)
        else:
            response = None
        return response

    @staticmethod
    def get_response_mock_test_self():
        """
        获取响应内容的字典,包括两部分,一部分是 "response_head",一部分是"response_body"
        @return:
        """

        response = {
            "status": 0,
            "msg": "成功"
        }
        return response

    @classmethod
    def get_initial_data_request_replay(cls):
        """
        读取初始设备模式和状态的回复
        :return:
        """
        opMode = "1"  # 自动模式
        if ec.operation_mode == "手动模式":
            opMode = "0"
        elif ec.operation_mode == "半自动模式":
            opMode = "2"

        plcState = "1"  # 闲置
        if ds.cutPlcState.isRun:
            plcState = "2"  # 运行
        if ds.cutPlcState.isRs:
            plcState = "0"  # 异常/停机

        response = {
            "success": True,
            "error": {
                "message": None,
                "details": None
            },
            "result": {
                "date_time": get_datatime_now_str(),
                "operation_mode": opMode,
                "total_wip_count": ds.totalWipCount,
                "equipment_status": plcState,
                "recipe_name": ds.orderUsedId
            }
        }
        return response



    @classmethod
    def get_trace_data_request_replay(cls):
        """
        获取追溯数据的回复
        :return:
        """
        dataList = [
            {"data_no":"1","data_item":"拍照移动速度","data_value":str(ec.moveSpeed)},
            {"data_no":"2","data_item":"拍照回退速度","data_value":str(ec.backSpeed)},
            {"data_no":"3","data_item":"机器人工作速度","data_value":str(ec.robotWorkSpeed)},
        ]

        traceDataList = {
            "trace_data": dataList
        }



        response = {
            "success": True,
            "error": {
                "message": None,
                "details": None
            },
            "result": {
                "trace_data_list": traceDataList
            }
        }
        return response

    @staticmethod
    def get_eap_orders_from_web():
        """
        主动从web端获取Eap工单列表
        """
        update_eap_orders_in_web()
        return DataResult(state=True)